package org.apache.seata.config;

import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;

/**
 * @author majinhui
 * @description
 * @create 2024/8/29 11:55
 **/
@Configuration
public class MyRabbitConfig {

    @Autowired
    private RabbitTemplate rabbitTemplate;
    /**
     * 定制RabbitTemplate
     * 1、服务收到消息就会回调
     *      1、spring.rabbitmq.publisher-confirms: true
     *      2、设置确认回调
     * 2、消息正确抵达队列就会进行回调
     *      1、spring.rabbitmq.publisher-returns: true
     *         spring.rabbitmq.template.mandatory: true
     *      2、设置确认回调ReturnCallback
     *
     * 3、消费端确认(保证每个消息都被正确消费，此时才可以broker删除这个消息)
     *   1、默认是自动确认的，只要消息收到，客户端会自动确认，服务端就回移除这个消息
     *   问题：收到了很多消息，自动回复给服务器ack，但是只要服务器宕机，就会发生消息丢失的情况。
     *      手动确认模式：只要我们没有明确告诉MQ，没有ack消息就一直是unacked状态。及时consumer宕机消息也不会丢失
     *   2、 如何签收：
     *       channel.basicAck(deliveryTag,false); 签收；业务成功完成就应该签收
     *       channel.basicNack(deliveryTag,false,true); 拒签；业务失败，拒签后消息重新入队
     */
    @PostConstruct
    public void initRabbitTemplate() {
        rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {
            System.out.println("confirm...correlationData-->" + correlationData);
            System.out.println("ack...ack-->" + ack);
            System.out.println("cause...cause-->" + cause);
        });

        /**
         * 只要消息没有投递给指定的队列，就触发这个失败回调
         * message：投递失败的消息详细信息
         * replyCode：回复的状态码
         * replyText：回复的文本内容
         * exchange：当时这个消息发给哪个交换机
         * routingKey：当时这个消息用哪个路邮键
         */
        rabbitTemplate.setReturnCallback((message, replyCode, replyText, exchange, routingKey) -> {
            System.out.println("Fail Message[" + message + "]==>replyCode[" + replyCode + "]" +
                    "==>replyText[" + replyText + "]==>exchange[" + exchange + "]==>routingKey[" + routingKey + "]");
        });
    }

}
